package com.heima.srevice.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.domain.dto.OrderDetailDTO;
import com.heima.domain.po.Item;
import com.heima.domain.po.ItemFreeze;
import com.heima.mapper.ItemFreezeMapper;
import com.heima.mapper.ItemMapper;
import com.heima.srevice.ItemFreezeService;
import com.hmall.common.exception.BizIllegalException;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class ItemFreezeServiceImpl extends ServiceImpl<ItemMapper, Item> implements ItemFreezeService {
    private final ItemFreezeMapper itemFreezeMapper;

    @Override
    public void deductStock(List<OrderDetailDTO> items) {
        //判断是否存在对应的冻结回滚记录，防止空悬挂
        String xid = RootContext.getXID();
        ItemFreeze itemFreeze = itemFreezeMapper.selectById(xid);
        if(itemFreeze != null && itemFreeze.getState() != ItemFreeze.State.CANCEL){
                return;
        }
        String sqlStatement = "com.heima.item.mapper.ItemMapper.updateStock";
        boolean r = false;
        try {
            r = executeBatch(items, (sqlSession, entity) -> sqlSession.update(sqlStatement, entity));
            //记录冻结数据
            itemFreeze.builder()
                    .xid(xid)
                    .state(ItemFreeze.State.TRY)
                    .freezeCount(JSONUtil.toJsonStr(items))
                    .build();
        }catch (Exception e){
            log.error("更新库存异常", e);
            return;
        }
        if (!r) {
            throw new BizIllegalException("库存不足！");
        }
    }

    /**
     * 提交
     */
    @Override
    public boolean confrim(BusinessActionContext ctx) {
        // 让try业务生效
         // status = 1 confrim
        String xid = ctx.getXid();
        return itemFreezeMapper.deleteById(xid)>0;
    }

    /**
     * 回滚
     */
    @Override
    public boolean cancel(BusinessActionContext ctx) {
        //1、获取xid
        String xid = ctx.getXid();
        //2、查询冻结数据
        ItemFreeze itemFreeze = itemFreezeMapper.selectById(xid);
        //2.1 如果冻结数据未null，证明try还未添加对应数据，这里可以添加一条已回滚的记录
        if(itemFreeze == null){
            ItemFreeze.builder()
                    .xid(xid)
                    .state(ItemFreeze.State.CANCEL)
                    .build();
            //添加记录，防止业务悬挂
            itemFreezeMapper.insert(itemFreeze);
            return true;
        }
        //3、批量回滚
        List<OrderDetailDTO> orderDetailDTOS = JSONUtil.toList(itemFreeze.getFreezeCount(), OrderDetailDTO.class);
        if(orderDetailDTOS != null){
            orderDetailDTOS.forEach(item->{
                lambdaUpdate().setSql("stock=stock+"+item.getNum())
                        .eq(Item::getId,item.getItemId())
                        .update();
            });
        }
        //4、状态记录
        itemFreeze.setState(ItemFreeze.State.CANCEL);
        itemFreezeMapper.updateById(itemFreeze);
        return true;
    }
}
